<?php
namespace app\adminapiv3\middleware;


use app\adminapiv3\service\Method;
use app\common\model\FilePath;
use app\common\model\HostModuleRelation;
use app\common\service\RSA;
use app\common\service\ServerAllowIp;
use app\common\service\ServerAuth;
use think\facade\Request;

class Check
{
    public function handle ($request, \Closure $next)
    {
        $controller = $request->controller();
        $action = $request->action();


        //判断是否是安装
        if (strtolower($controller) == 'install') {
            return $next($request);
        }

        $nowRoute = $request->url();


        //1. 验证是否安装
        if(strtolower($controller) == 'index' && strtolower($action) == 'isinstall'){

            return $next($request);
        }
        $this->install();


        if($nowRoute == '/test'){
            return $next($request);
        }

        //首页攻击统计
        $statisticsRoute = 'adminapi/v3/index/manage/public/attackratio';

        if(!strpos($nowRoute, $statisticsRoute)){
            if ($this->noCheck($nowRoute)) {
                return $next($request);
            }
        }


        //用户验证
        $token = $request->accesstoken;
        $clientIp = $request->ip();//客户端ip

        //检测非法IP
        $this->checkAllowIp($clientIp);
        
        $user = $this->checkToken($token, $clientIp);

        $request->user_info = $user;

        //权限验证
        if (!strpos($nowRoute, $statisticsRoute)) {
            $this->checkPermissions($nowRoute, $user);
        }


        return $next($request);
    }


    /**
     * @name 安装
     * @return bool
     * @author wx
     * @date 2019/11/25 16:39
     */
    function install()
    {

        $filePathServer = new FilePath();
        $installFileName = $filePathServer->install_path;
        $systemTimeFile = $filePathServer->system_time;

        if (file_exists($installFileName) && file_exists($systemTimeFile)) {
            return true;
        }else{
            jsonErrorOut('该系统未安装,请先完成安装', 101);
        }
    }

    /**
     * @name 不用验证方法
     * @param $nowRoute
     * @author wx
     * @date 2020/7/9 13:16
     *
     */
    function noCheck($nowRoute){
        preg_match('/(.*?)\/manage\/(public).*/i',$nowRoute, $actionArr);

        if(!empty($actionArr)){
            return true;
        }
    }

    /**
     * @name 检测合法ip
     * @param $ip
     * @author wx
     * @date 2021/1/7 12:57
     */
    public function checkAllowIp($ip)
    {
        $ipCount = db('server_allow_ip')->where('ip', $ip)->count();
        if(!$ipCount){
            jsonErrorOut('非法IP', 101);
        }
    }

    /**
     * @name 用户token
     * @return bool
     * @author wx
     * @date 2019/11/25 16:40
     */
    function checkToken($token, $clientIp)
    {
        if(empty($token)){
            jsonErrorOut('登录凭证为空', 300);
        }

        //查询用户
        $user = db('server_user')->alias('su')
            ->join('server_user_group sg', 'su.user_group_id = sg.id')
            ->field('su.id, last_login_time, last_login_ip, real_name, user_group_id, level as user_group_level')
            ->where('token', $token)->find();

        if (empty($user))
        {
            jsonErrorOut('身份验证失败', 300);
        }

        //最后登录时间
        if($user['last_login_time'] + 86400 <= time())
        {
            jsonErrorOut('登录时间过期', 300);
        }


        if($user['last_login_ip'] != $clientIp)
        {
            jsonErrorOut('已被其他人登录', 300);
        }


        return $user;
    }

    /**
     * @name 权限
     * @return bool
     * @author wx
     * @date 2019/11/25 16:42
     */
    function checkPermissions($nowRoute, $user)
    {

        preg_match('/\/(.*?)\/manage\/(do\/clear|do\/delete|do|get|excute).*/i',$nowRoute, $actionArr);

        if(!$actionArr){
            jsonErrorOut('无效链接', 100);
        }
        

        $action = $actionArr[1];//具体模块
        $option = $actionArr[2];//具体操作


        $permissionList = [
            'do/clear' => ['is_delete', '删除'],
            'do/delete' => ['is_delete', '删除'],
            'do' => ['is_do', '修改'],
            'get' => ['is_get', '查看'],
            'excute' => ['is_excute','其他'],
        ];

        if (!in_array($option, array_keys($permissionList))) {
            jsonErrorOut('无效链接', 101);
        }

        $optionField = $permissionList[$option];


        //查询用户权限
        $count = db('server_permissions')->alias('sp')
            ->join('server_user_permissions_relation sr', 'sp.id = sr.permissions_id')
            ->where('url', $action)
            ->where($optionField[0],1)
            ->where('user_id', $user['user_group_id'])
            ->count();

        if($count == 0){

            $res = strpos($nowRoute, 'adminapi/v3/log/network/attack/manage/get/warning');

            if($res){
                jsonErrorOut('当前用户对本模块不具备[ '.$optionField[1].' ]权限', 103);
            }

            jsonErrorOut('当前用户对本模块不具备[ '.$optionField[1].' ]权限', 102);
        }

        return true;
    }


}